use bevy::prelude::*;
use crate::GameState;
use crate::ui::game_map::{GameDirection, MapPanelRelate, Moving};

#[derive(Component)]
pub struct Colider {
    pub width: f32,
    pub height: f32,
}

pub struct ColiderPlugin;

impl Plugin for ColiderPlugin {
    fn build(&self, app: &mut App) {
        app.add_systems(Update, (check_collision, check_map_collision).run_if(in_state(GameState::Gaming)));
    }
}

fn check_collision(
    mut query_movable: Query<(&mut Transform, &Colider, &Moving), With<Moving>>,
    query: Query<(&Colider, &Transform), (Without<Moving>, Without<MapPanelRelate>)>,
) {
    for (mut transform, rect, mov) in query_movable.iter_mut() {
        for (collider, st_transform) in query.iter() {
            if transform.translation.y + rect.height / 2.0 > st_transform.translation.y - collider.height / 2.0
                && transform.translation.y - rect.height / 2.0 < st_transform.translation.y + collider.height / 2.0
                && transform.translation.x + rect.width / 2.0 > st_transform.translation.x - collider.width / 2.0
                && transform.translation.x - rect.width / 2.0 < st_transform.translation.x + collider.width / 2.0
            {
                match mov.direction {
                    GameDirection::Up => {
                        transform.translation.y = st_transform.translation.y - collider.height / 2.0 - rect.height / 2.0;
                    }
                    GameDirection::Down => {
                        transform.translation.y = st_transform.translation.y + collider.height / 2.0 + rect.height / 2.0;
                    }
                    GameDirection::Left => {
                        transform.translation.x = st_transform.translation.x + collider.width / 2.0 + rect.width / 2.0;
                    }
                    GameDirection::Right => {
                        transform.translation.x = st_transform.translation.x - collider.width / 2.0 - rect.width / 2.0;
                    }
                }
            }
        }
    }
}

fn check_map_collision(
    mut query_movable: Query<(&mut Transform, &Colider, &Moving), With<Moving>>,
    query: Query<&Colider, With<MapPanelRelate>>,
) {
    for (mut transform, rect, mov) in query_movable.iter_mut() {
        for collider in query.iter() {
            match mov.direction {
                GameDirection::Up => {
                    if transform.translation.y + rect.height / 2.0 > collider.height / 2.0 {
                        transform.translation.y = collider.height / 2.0 - rect.height / 2.0;
                    }
                }
                GameDirection::Down => {
                    if transform.translation.y - rect.height / 2.0 < -collider.height / 2.0 {
                        transform.translation.y = -collider.height / 2.0 + rect.height / 2.0;
                    }
                }
                GameDirection::Left => {
                    if transform.translation.x - rect.width / 2.0 < -collider.width / 2.0 {
                        transform.translation.x = -collider.width / 2.0 + rect.width / 2.0;
                    }
                }
                GameDirection::Right => {
                    if transform.translation.x + rect.width / 2.0 > collider.width / 2.0 {
                        transform.translation.x = collider.width / 2.0 - rect.width / 2.0;
                    }
                }
            }
        }
    }
}